import '../http.dart';
import 'package:safety_platform/models/task_page.dart';
import 'package:safety_platform/models/task.dart';
import 'package:safety_platform/models/attachment.dart';
import 'package:safety_platform/models/situation.dart';
import 'dart:io';
import 'dart:convert';
import 'package:image_jpeg/image_jpeg.dart';
import 'package:safety_platform/models/classification.dart';
import 'package:safety_platform/models/classification_page.dart';
import 'package:safety_platform/models/hidden_danger.dart';
import 'package:safety_platform/models/rectify_step.dart';
import 'package:safety_platform/models/risk_unit.dart';
import 'package:safety_platform/models/advertisement.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:safety_platform/utils.dart' show formatDate;
import 'package:dio/dio.dart';
import 'dart:convert';

final _urlPrefix = '/risk/task/today/';

class ServiceException implements Exception {
  final String message;
  ServiceException(this.message);
}

void _catchError(e) {
  print('Catch erro $e');
  if (e is DioError) {
    DioErrorType type = e.type;
    switch (type) {
      case DioErrorType.RESPONSE:
        {
          int httpCode = e.response.statusCode;
          if (httpCode >= 400 && httpCode <= 500) {
            dynamic errors = e.response.data;

            print(errors);


            throw ServiceException(errors['detail']);
          }
          throw ServiceException(e.response.data);
        }
      case DioErrorType.RECEIVE_TIMEOUT:
        {
          break;
        }
      case DioErrorType.CONNECT_TIMEOUT:
        {
          break;
        }
      case DioErrorType.CANCEL:
        {
          break;
        }
      case DioErrorType.DEFAULT:
        {
          throw Exception(e.message);
          break;
        }
    }
  }
}

// class TimeoutException implements ServiceException {
//   TimeoutException() {
//     ('Time Out');
//   }
// }
Future<List<Classification>> loadClassification({String code}) async {
  final url = '/risk/classifications/';
  Map<String, String> data = {
    'page_size': 1000.toString(),
    'parent_id': code,
  };

  var resp = await httpGet(url, data: data,cache: true);

  ClassificationPage page = ClassificationPage.fromJson(resp);

  return page.results;
}


Future<Task> loadTask(String taskId) async {
  final String url = '/task/$taskId/';

  var data = await httpGet(url);

  return Task.fromJson(data);
}

Future<HiddenDanger> submitTaskHiddenDanger(
    String taskId, TaskHiddenDangerRequest request) async {
  final String url = '/task/$taskId/hidden_dangers/';
  var res = await httpPost(url, data: request.toJson());

  return HiddenDanger.fromJson(res);
}

Future<HiddenDanger> submitHiddenDanger(HiddenDangerRequest request) async {
  final String url = '/hidden_dangers/';

  var data = await httpPost(url, data: request.toJson());

  return HiddenDanger.fromJson(data);
}

Future<List<RiskUnit>> fetchAllRiskUnit() async {
  final String url = '/risk_unit/';
  Map<String, String> data = Map();
  data['page_size'] = '1000';

  var res = await httpGet(url, data: data,cache: true);

  return RiskUnitPage.fromJson(res).results;
}

Future<List<HiddenDanger>> fetchHiddenDangerFromTask(Task task) async {
  final String url = '/task/${task.id}/hidden_dangers/';

  var res = await httpGet(url);

  List<HiddenDanger> results = List();

  for (dynamic r in res) {
    results.add(HiddenDanger.fromJson(r));
  }
  return results;
}

Future<HiddenDangerPage> fetchHiddenDanger(
    {int page = 1, int pageSize = 10, String status, String level}) async {
  final String url = '/hidden_dangers/';
  Map<String, String> data = Map();
  data['page'] = page.toString();
  data['page_size'] = pageSize.toString();
  data['status'] = status;
  if (level != null) {
    data['grade'] = level;
  }

  var res = await httpGet(url, data: data);
  return HiddenDangerPage.fromJson(res);
}

Future<HiddenDanger> submitHiddenDangerVerified(
    HiddenDanger hiddenDanger) async {
  final url = '/hidden_dangers/${hiddenDanger.id}/verified/';

  Map<String, dynamic> data = Map();

  data['memo'] = hiddenDanger.memo;

  if (hiddenDanger.verifiedImages != null) {
    data['verified_images'] = hiddenDanger.verifiedImages.map((attach) {
      return attach.toJson();
    }).toList();
  }

  try {
    var res = await httpPost(url, data: data);
    return HiddenDanger.fromJson(res);
  } on DioError catch (e) {
    _catchError(e);
  }
}

Future<HiddenDanger> submitHiddenDangerDone(HiddenDanger hiddenDanger) async {
  final url = '/hidden_dangers/${hiddenDanger.id}/done/';

  Map<String, dynamic> data = Map();
  // data['rectification_cost'] = hiddenDanger.rectificationCost;

  List<dynamic> situationsData = hiddenDanger.situations.map((s) {
    return s.toJson();
  }).toList();
  data['situations'] = situationsData;
  data['attachments'] =
      hiddenDanger.attachments.map((a) => a.toJson()).toList();

  var res = await httpPost(url, data: data);

  return HiddenDanger.fromJson(res);
}

Future<HiddenDanger> submitHiddenDangerRectification(String hiddenDangerId,
    bool rectifyed, DateTime rectifyDate, String budget) async {
  final usl = '/hidden_dangers/$hiddenDangerId/approved/';

  Map<String, dynamic> data = Map();

  data['need_rectification'] = rectifyed;
  if (rectifyDate != null) {
    data['rectify_date'] = formatDate(rectifyDate, format: 'yyyy-MM-dd');
  }

  data['rectification_budget'] = budget;

  var res = await httpPost(usl, data: data);

  return HiddenDanger.fromJson(res);
}

Future<List<Advertisement>> fetchAdvFromRemote({platform, position}) async {
  final url = '/advertisement/advertisements/';
  Map<String, String> map = {'page_size': 15.toString()};
  if (platform != null) {
    map['platform'] = platform;
  }
  if (position != null) {
    map['position'] = position;
  }

  var res = await httpGet(url, data: map);
  if (res != null) {

    SharedPreferences sp = await SharedPreferences.getInstance();

    sp.setString('__adv_home', json.encode(res));
    AdvertisementPage page = AdvertisementPage.fromJson(res);

    List<Advertisement> results = page.results;

    if (results != null) {
      return results;
    }
  }
  return null;
}

Future<List<Advertisement>> fetchAdvFormCache() async {
  SharedPreferences sp = await SharedPreferences.getInstance();

  String advStr = sp.getString('__adv_home');

  if (advStr != null) {
    List<Advertisement> advList = List();
    var advJson = json.decode(advStr);

    for (var j in advJson) {
      advList.add(Advertisement.fromJson(j));
    }
    return advList;
  }
  return null;
}



Future<Attachment> uploadPicture(File image, String fileName,
    {String prefix}) async {
  Map<String, dynamic> ext = Map();
  ext['prefix'] = prefix;

  var sv = await ImageJpeg.getInfo(image.path);
  print('图像信息: $sv');
  String newFileName = DateTime.now().microsecondsSinceEpoch.toString();
  String newFilePath = await ImageJpeg.encodeJpeg(
      image.path,
      '${image.parent.path}/$newFileName.jpg',
      75,
      (sv.width * 0.80).toInt(),
      (sv.height * 0.80).toInt());

  var sv2 = await ImageJpeg.getInfo(newFilePath);
  print('压缩后图像信息: $sv2');
  print('上传图像: $newFilePath');
  var data = await httpUploadImg(File(newFilePath), fileName, ext: ext);
  return Attachment.fromJson(data);
}

Future<Attachment> uploadAttachment(Attachment attachment,
    {String target}) async {
  try {
    print('上传文件开始');
    var data = await httpUpload(File(attachment.localPath), target: target);
    print('上伟文件结束，结果：$data');
    Attachment attach = Attachment.fromJson(data);
    attach.uploadStatus = 'done';
    return attach;
  } on DioError catch (e) {
    print(e.response);
  }
  return attachment;
}

// Future<Attachment> uploadFile(File file, String fileName, )
